package com.md.api.scheduled;

import com.aliyun.oss.model.StorageClass;
import com.md.api.common.exception.BusinessException;
import com.md.api.common.utils.*;
import com.md.api.dao.*;
import com.md.api.entity.*;
import com.md.api.entity.enums.OssStorageClassLevel;
import com.md.api.entity.enums.PictureStatus;
import com.md.api.entity.enums.UserStatus;
import com.md.api.entity.enums.VipStatus;
import com.md.api.service.UserSevice;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 * @ClassName SolrIncrementTask
 * @Description 增量更新定时任务
 * @Author 刘杰
 * @Date 2019/8/8 10:09
 * @Version 1.0
 **/
@Component
@Slf4j
public class RecycleBinTask {
    @Resource
    private RecycleBinMapper recycleBinMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private UserFtpMapper ftpMapper;
    @Resource
    private UserVipMapper vipMapper;
    @Resource
    private PhotoInfoMapper photoMapper;
    @Resource
    private PictureInfoMapper pictureMapper;
    @Autowired
    private MessageMapper sysMessageDao;
    @Resource
    private UserSevice userSevice;
    /**
     * 定时处理回收站到期图片
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void handleRecycleBin(){
        List<RecycleBin> sList = recycleBinMapper.getDeleteList();
        if (!CollectionUtils.isEmpty(sList)) {
            for(RecycleBin recycleBin:sList){
                try {
                    if (recycleBin.getRecycleType()==2){
                        UserInfo user = userMapper.getByUserId(recycleBin.getUserId());
                        BigDecimal num1 = new BigDecimal(user.getUseStorage());
                        BigDecimal num2 = new BigDecimal(recycleBin.getSize());
                        user.setUseStorage(num1.subtract(num2).doubleValue());
                        userMapper.updateUseStorage(user);
                        AliOssUtil.delShopImage(recycleBin.getDisplayImageUrl());
                        PictureInfo byPictureId = pictureMapper.getByPictureId(recycleBin.getOnlyId());
                        if (null!=byPictureId){
                            if (StringUtils.isNotEmpty(byPictureId.getFaceId())){
                                PhotoInfo byPhotoId = photoMapper.getByPhotoId(byPictureId.getPhotoId());
                                FaceRecognitionUtil.deleteFace(byPhotoId.getFaceDbId(),byPictureId.getFaceId());
                                FaceRecognitionUtil.deleteFaceEntity(byPhotoId.getFaceDbId(),byPictureId.getPictureId());
                            }
                        }
//                    }else if(recycleBin.getRecycleType()==1){
//                        //相册需要删除人脸库
//                        FaceRecognitionUtil.deleteFaceDb(recycleBin.getOnlyId());
                    }
                    recycleBinMapper.deleteById(recycleBin.getId());
                } catch (Exception e) {
                    log.error("RecycleBinTask.handleRecycleBin() error",e);
                    continue;
                }
            }
        }
        log.info("定时处理回收站到期图片完毕");
    }


    /**
     * 定时处理即将到期会员推送
     */
    @Scheduled(cron = "0 0 9 * * ?")
    public void handleLatestExpireVip(){
        List<UserVip> sList = vipMapper.getLatestExpireVip();
        if (!CollectionUtils.isEmpty(sList)) {
            for(UserVip userVip:sList){
                try {
                    UserInfo user = userMapper.getByUserId(userVip.getUserId());
                    if (StringUtils.isNotEmpty(user.getEmail())){
                        SendMail vo = new SendMail();
                        vo.setEmail(user.getEmail());
                        vo.setSubject("會員即將到期提醒");
                        String content= "您的會員：\""+userVip.getServiceName()+"\"即將到期，爲保障您的正常使用，請及時續費！";
                        vo.setContent(content);
                        try {
                            EmailUtil.sendMail(vo);
                        }catch (Exception e){
                            e.printStackTrace();
                            throw new BusinessException("會員即將到期提醒郵箱發送失敗！");
                        }
                        SysMessage message = new SysMessage();
                        message.setReceiveUser(user.getEmail());
                        message.setContent(content);
                        message.setMsgType("email");
                        sysMessageDao.save(message);
                    }
                    if (StringUtils.isNotEmpty(user.getPhone())){
                        String content= "您的會員：\""+userVip.getServiceName()+"\"即將到期，爲保障您的正常使用，請及時續費！";
                        SmsInternationUtils.sendSms(user.getPhone(), content);
                        SysMessage message = new SysMessage();
                        message.setReceiveUser(user.getPhone());
                        message.setMsgType("phone");
                        message.setContent(content);
                        sysMessageDao.save(message);
                    }
                } catch (Exception e) {
                    log.error("RecycleBinTask.handleLatestExpireVip() error",e);
                    continue;
                }
            }
        }
        log.info("定时处理即将到期会员推送完毕");
    }


    /**
     * 定时处理今日到期会员降级
     */
    @Scheduled(cron = "0 30 0 * * ?")
    public void handleExpireVip(){
        List<UserVip> sList = vipMapper.getExpireVip();
        if (!CollectionUtils.isEmpty(sList)) {
            int count = 0;
            for(UserVip userVip:sList){
                try {
                    userVip.setStatus(VipStatus.USED.value());
                    vipMapper.updateVip(userVip);
                    int i = ftpMapper.deleteByUserId(userVip.getUserId());
                    count = count+i;
                } catch (Exception e) {
                    log.error("RecycleBinTask.handleExpireVip() error",e);
                    continue;
                }
            }
            if (count>0){
                userSevice.resetFtpFile();
            }
        }
        log.info("定时处理今日到期会员降级完毕");
    }

    /**
     * 定时处理resetFtpFile
     */
    @Scheduled(cron = "0 10 0 * * ?")
    public void resetFtpFile(){
        userSevice.resetFtpFile();
        log.info("定时处理resetFtpFile完毕");
    }

    /**
     * 定时处理相册、相片状态
     * //0正常  1一级锁定（30天到期未续费）  2 二级锁定（60天到期未续费）   3 三级锁定（270天到期未续费）
     */
    @Scheduled(cron = "0 30 0 * * ?")
    public void handleExpirePicture(){
        pictureMapper.handleExpirePicture();
        log.info("定时处理相册、相片状态完毕");
    }

    /**
     * 定时处理到期未续费会员状态
     * //0正常  1一级锁定（30天到期未续费）  2 二级锁定（60天到期未续费）   3 三级锁定（270天到期未续费）
     */
    @Scheduled(cron = "0 30 0 * * ?")
    public void handleExpireUser(){
        vipMapper.handleExpireUser();
        log.info("定时处理到期未续费会员状态完毕");
    }

//0正常  1一级锁定  2 二级锁定   3 三级锁定
//摄影师版本/企业版到期没有续费，即刻禁止上传照片
//到期没续费起算，30天，存储空间冻结访问
//摄影师打不开相册，email提醒续费，每7天一次
//普通用户也看不到照片
    @Scheduled(cron = "0 0 1 * * ?")
    public void handleFirstLevelLocked(){
        List<UserInfo> list = userMapper.getUserByStatus(UserStatus.FIRST_LEVEL_LOCKED.value());
        for (UserInfo user:list){
            photoMapper.lockUserPhoto(user.getUserId());
        }
    }
    @Scheduled(cron = "0 0 9 ? * SUN")
    public void handleFirstLevelLockedEmail(){
        List<UserInfo> list = userMapper.getUserByStatus(UserStatus.FIRST_LEVEL_LOCKED.value());
        for (UserInfo user:list){
            if (StringUtils.isEmpty(user.getEmail())){
                continue;
            }
            SendMail vo = new SendMail();
            vo.setEmail(user.getEmail());
            vo.setSubject("會員到期續費提醒");
            String content= "您的會員已到期超過30天，相冊功能已無法使用，爲保障您的正常使用，請及時續費！";
            vo.setContent(content);
            try {
                EmailUtil.sendMail(vo);
            }catch (Exception e){
                e.printStackTrace();
                throw new BusinessException("會員已到期超過30天提醒郵箱發送失敗！");
            }
        }
    }

    //到期没续费起算60天(将所有照片放去oss冷归档)
    //摄影师打不开相册，email提醒显示账户被封锁，请联络管理员解锁账号。7天一次
    //普通用户看不到照片
    @Scheduled(cron = "0 0 1 * * ?")
    public void handleSecondLevelLocked(){
        List<UserInfo> list = userMapper.getUserByStatus(UserStatus.SECOND_LEVEL_LOCKED.value());
        for (UserInfo user:list){
            List<PictureInfo> pictureList = pictureMapper.getLessPicByUserId(user.getUserId(), OssStorageClassLevel.ColdArchive.value());
            for (PictureInfo pic:pictureList){
                AliOssUtil.resetStorageClass(pic.getPictureUrl(), StorageClass.ColdArchive);
                pic.setOssStorageClass(StorageClass.ColdArchive.toString());
                pic.setOssStorageClassLevel(OssStorageClassLevel.ColdArchive.value());
                pic.setStatus(PictureStatus.COLDING.value());
                pictureMapper.updatePicture(pic);
            }
        }
    }
    @Scheduled(cron = "0 0 9 ? * SUN")
    public void handleSecondLevelLockedEmail(){
        List<UserInfo> list = userMapper.getUserByStatus(UserStatus.SECOND_LEVEL_LOCKED.value());
        for (UserInfo user:list){
            if (StringUtils.isEmpty(user.getEmail())){
                continue;
            }
            SendMail vo = new SendMail();
            vo.setEmail(user.getEmail());
            vo.setSubject("會員到期續費提醒");
            String content= "您的會員已到期超過60天，賬號已被封鎖，請聯係管理員解鎖賬號！";
            vo.setContent(content);
            try {
                EmailUtil.sendMail(vo);
            }catch (Exception e){
                e.printStackTrace();
                throw new BusinessException("會員封鎖提醒郵箱發送失敗！");
            }
        }
    }

    //  到期没续费起算270天冷归档照片都删除  提前有email提醒
    @Scheduled(cron = "0 0 12 * * ?")
    public void handleThreeLevelLocked(){
        List<UserInfo> list = userMapper.getUserByStatus(UserStatus.THREE_LEVEL_LOCKED.value());
        for (UserInfo user:list){
            List<PictureInfo> pictureList = pictureMapper.getMostPicByUserId(user.getUserId(), OssStorageClassLevel.ColdArchive.value());
            for (PictureInfo pic:pictureList){
                pictureMapper.deleteByPictureId(pic.getPictureId());
                AliOssUtil.delShopImage(pic.getPictureUrl());
                if (StringUtils.isNotEmpty(pic.getFaceId())){
                    PhotoInfo byPhotoId = photoMapper.getByPhotoId(pic.getPhotoId());
                    FaceRecognitionUtil.deleteFace(byPhotoId.getFaceDbId(),pic.getFaceId());
                    FaceRecognitionUtil.deleteFaceEntity(byPhotoId.getFaceDbId(),pic.getPictureId());
                }
            }
            //清理ftp文件夹
            UserFtp ftpUser = ftpMapper.getByUserId(user.getUserId());
            if (null!=ftpUser) {
                AliOssUtil.delShopImage(AliOssUtil.DOMAIN + "/"+ftpUser.getHomeDir());
            }
        }
    }
    @Scheduled(cron = "0 0 9 * * ?")
    public void handleThreeLevelLockedEmail(){
        List<UserInfo> list = userMapper.getUserByStatus(UserStatus.SECOND_LEVEL_LOCKED.value());
        for (UserInfo user:list){
            List<PictureInfo> pictureList = pictureMapper.getMostPicByUserId(user.getUserId(), OssStorageClassLevel.ColdArchive.value());
            if (StringUtils.isEmpty(user.getEmail())||CollectionUtils.isEmpty(pictureList)){
                continue;
            }
            SendMail vo = new SendMail();
            vo.setEmail(user.getEmail());
            vo.setSubject("會員到期續費提醒");
            String content= "您的會員已到期超過270天，賬號下的照片將被清理！";
            vo.setContent(content);
            try {
                EmailUtil.sendMail(vo);
            }catch (Exception e){
                e.printStackTrace();
                throw new BusinessException("會員封鎖提醒郵箱發送失敗！");
            }
        }
    }


    //批量查看解冻中的图片在oss的解冻状态
    @Scheduled(cron = "0 0 */1 * * ?")
    public void handleThawingStatus(){
        List<PictureInfo> pictureList = pictureMapper.getPictureByStatus(PictureStatus.THAWING.value());
        for (PictureInfo pic:pictureList){
            boolean thawingStatus = AliOssUtil.getThawingStatus(pic.getPictureUrl());
            if (thawingStatus){
                AliOssUtil.resetStorageClass(pic.getPictureUrl(),StorageClass.Standard);
                pic.setOssStorageClass(StorageClass.Standard.toString());
                pic.setOssStorageClassLevel(OssStorageClassLevel.Standard.value());
                pic.setStatus(PictureStatus.NORMAL.value());
                pictureMapper.updatePicture(pic);
            }
        }
    }


    //批量查看创建30天后或今日活动结束的相册
    //需要删除人脸库数据
    @Scheduled(cron = "0 0 1 * * ?")
    public void handleNoFacePhoto(){
        List<PhotoInfo> photoInfos = photoMapper.getNoFacePhoto();
        for (PhotoInfo photoInfo:photoInfos){
            List<PictureInfo> pictures = pictureMapper.getByPhotoId(photoInfo.getPhotoId(),null,null);
            for (PictureInfo pic:pictures){
                if (StringUtils.isNotEmpty(pic.getFaceId())){
                    PhotoInfo byPhotoId = photoMapper.getByPhotoId(pic.getPhotoId());
                    FaceRecognitionUtil.deleteFace(byPhotoId.getFaceDbId(),pic.getFaceId());
                    FaceRecognitionUtil.deleteFaceEntity(byPhotoId.getFaceDbId(),pic.getPictureId());
                }
            }
        }
    }
}
